use encoding::all::UTF_16LE;
use encoding::{DecoderTrap, EncoderTrap, Encoding};
use fsio::{directory, file, path};
use std::{error::Error, thread::sleep, time::Duration};
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use walkdir::WalkDir;
fn main() {
    // return;
    for entry in WalkDir::new("config").into_iter().filter_map(|e| e.ok()) {
        if entry.file_type().is_file(){
            let ext = entry.path().extension();
            if ext.is_none(){
                continue;
            }
            // println!("exten={:?}",entry.path().extension().unwrap());
            if ext.unwrap().ne("txt"){
                continue;
            }
            println!("{}", entry.path().display());

            let txt = file::read_file(&entry.path()).unwrap();
            // println!("txt={:?}", txt);

            let mut dst = UTF_16LE.decode(&txt, DecoderTrap::Strict).unwrap();

            // let mut d = UTF_8.new_decoder();

            // let s = d.decode_to_string(&txt, &mut dst, true);
            // println!("s={:?}", s);
            // let mut d = DecodeReaderBytes::new(&txt[..]);
            // d.read_to_string(&mut dst);
            // println!("dst={:?}",dst);
            let mut out_file = String::from("output/");
            out_file.push_str(entry.file_name().to_str().unwrap());
            change(&mut dst, &out_file);
        }
    }
    println!("转换完成!");
    sleep(Duration::from_secs(30));
}

fn change(s: &mut String, out: &String) {
    let mut new_lines: Vec<String> = Vec::new();
    let lines: Vec<&str> = s.lines().filter(|line| {line.split_ascii_whitespace().count() > 0}).collect();
    let empty = String::from("");
    for index in 0..lines.len() {
        let line = lines[index];
        let mut old_line: String = String::new();
        // line.split_ascii_whitespace()
        //     .fold(&mut old_line, |line, v| {
        //         line.push_str(format!("{}\t\t\t", v).as_str());
        //         line
        //     });
        let mut slins: Vec<String> = Vec::new();
        line.split_ascii_whitespace().fold(&mut slins, |slins, v| {
            slins.push(format!("{}\t\t\t", v));
            slins
        });
        old_line.push_str(slins[0].as_str());
        old_line.push_str(slins[1].as_str());
        match index {
            0 => new_lines.push(format!(
                "{}{}\t\t{}\t\t跑道数",
                old_line, "与上一行的时间差", "上下行中间的时间"
            )),
            1 => new_lines.push(format!(
                "{}{}\t\t{}\t\t\t{}",
                old_line, "\t\t\t", "\t\t\t", slins.get(2).unwrap_or(&empty).as_str()
            )),
            n if n > 1 && n < lines.len() => {
                //确定范围
                let pre_line_vals: Vec<&str> = lines[n - 1].split_ascii_whitespace().collect();
                let pre_durs: Vec<i32> = pre_line_vals[1]
                    .split(":")
                    .map(|x| x.parse::<i32>().unwrap())
                    .collect();
                let line_vals: Vec<&str> = line.split_ascii_whitespace().collect();
                let durs: Vec<i32> = line_vals[1]
                    .split(":")
                    .map(|x| x.parse::<i32>().unwrap())
                    .collect();
                // println!("line={:?},durs={:?}", line_vals[1], durs);

                let rates = [3600, 60, 1];
                //与上一行的时间差
                let pre_off_dur =
                    (durs[1] - pre_durs[1]) * 3600 + (durs[2] - pre_durs[2]) * 60 + durs[3]
                        - pre_durs[3];
                //上下行中间的时间

                let mid_off_str = if n <= lines.len() - 2 {
                    let next_line_vals: Vec<&str> = lines[n + 1].split_ascii_whitespace().collect();
                    let next_durs: Vec<i32> = next_line_vals[1]
                        .split(":")
                        .map(|x| x.parse::<i32>().unwrap())
                        .collect();
                    let pre_all_dur =
                        (0..rates.len()).fold(0, |acc, i| acc + pre_durs[i + 1] * rates[i]);
                    let pre_next_off_dur = ((0..rates.len())
                        .fold(0, |acc, i| acc + next_durs[i + 1] * rates[i])
                        - pre_all_dur) as f64
                        / 2.0
                        + pre_all_dur as f64;

                    (0..rates.len()).fold(
                        (String::from("00"), pre_next_off_dur),
                        |acc, i| match i {
                            2 => (
                                format!("{}:{:>04.1?}", acc.0.as_str(), acc.1 / rates[i] as f64),
                                acc.1 % rates[i] as f64,
                            ),
                            _ => (
                                format!(
                                    "{}:{:>02?}",
                                    acc.0.as_str(),
                                    (acc.1 / rates[i] as f64).floor() as i32
                                ),
                                acc.1 % rates[i] as f64,
                            ),
                        },
                    )
                } else {
                    ("\t\t\t\t".to_owned(), 0.)
                };

                // println!("midoffstr={:?}, tewst={}", mid_off_str.0, "got to schell");

                new_lines.push(format!(
                    "{}{:?}\t\t\t\t\t{}\t\t\t{}",
                    old_line, pre_off_dur, mid_off_str.0, slins.get(2).unwrap_or(&empty).as_str()
                ))
            }
            _ => new_lines.push(format!(
                "{}{}\t\t{}\t\t{}",
                old_line, "\t\t\t\t\t", "\t\t\t\t\t", slins.get(2).unwrap_or(&empty).as_str()
            )),
        }
        // println!("line={:?}", line);
    }
    // println!("new lines={:#?}", new_lines);
    let mut outstr: String = String::new();
    new_lines.iter().fold(&mut outstr, |sr, v| {
        sr.push_str(v);
        sr.push_str("\n");
        sr
    });
    // println!("outsr={}", outstr);

    let mut write = match File::create(out) {
        Ok(file) => file,
        Err(_) => std::process::exit(-3),
    };
    let mut out_buffer: Vec<u8> = Vec::new();
    UTF_16LE.encode_to(&outstr, EncoderTrap::Strict, &mut out_buffer);
    write.write_all(&out_buffer);
    write.flush();
}
